package com.usesion.base.shiro;

import com.usesion.entity.User;
import com.usesion.service.MenuService;
import com.usesion.service.RoleService;
import com.usesion.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @desc: 自定义Realm处理登录权限
 * @author: XT
 */
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private MenuService menuService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserService userService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Integer userId = ShiroUtils.getUserId();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roleService.selectRoleKeys(userId));
        authorizationInfo.setStringPermissions(menuService.selectPermsByUserId(userId));
        return authorizationInfo;
    }

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName = (String)token.getPrincipal();
        String password = new String((char[]) token.getCredentials());
        User user = userService.selectUserByUserName(userName);
        if(user == null){
            throw new UnknownAccountException("用户名不存在");
        }
        if (!matches(user, password)) {
            throw new IncorrectCredentialsException("用户名或密码不正确");
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        return info;
    }

    /**
     * 验证密码是否一致
     * @param user
     * @param newPassword
     * @return
     */
    public boolean matches(User user, String newPassword) {
        return user.getPassword().equals(encryptPassword(user.getUserName(), newPassword, user.getSalt()));
    }

    /**
     * 密码加密
     * @param username
     * @param password
     * @param salt
     * @return
     */
    public String encryptPassword(String username, String password, String salt) {
        return new Md5Hash(username + password + salt).toHex().toString();
    }

    /**
     * 清理缓存权限
     */
    public void clearCachedAuthorizationInfo() {
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

    /**
     * 明文密码加密存储在数据库
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(new UserRealm().encryptPassword("admin", "admin123", "123456"));
    }
}
